#!/usr/bin/env python
# _*_ coding:utf-8 _*_

import socketserver
import threading
import logging

FORMAT = '%(asctime)s %(threadName)s %(message)s'
logging.basicConfig(level=logging.INFO,format=FORMAT,datefmt="%Y-%m-%d %H:%M:%S")

clients = {}  #request实例 初始化容器

class Myhandler(socketserver.StreamRequestHandler):  #创建handler类

    def setup(self) -> None:   #利用setup初始化
        super().setup()
        self.rfile = self.request.makefile('r')
        self.wfile = self.request.makefile('w')
        self.event = threading.Event()
        self.lock = threading.Lock()


    def handle(self) -> None:
        super().handle()
        with self.lock:
            clients[self.client_address] = self
            logging.info(f'{self.client_address}连接成功')
        try:
            while not self.event.is_set():     
                data_makefile = self.rfile.readline().strip()
                #data = self.request.recv(1024)
                if data_makefile == '':     #断开判断
                    self.finish()
                    logging.info(f'{self.client_address}: 断开连接')
                    with self.lock:
                        clients.pop(self.client_address)
                    break

                #msg="{}".format(data_makefile.decode()).encode()
                msg = f"{data_makefile}"
                logging.info(f'server accpet : {self.client_address} :<%%%% {data_makefile} %%%%>')
                with self.lock:

                    for k,i in clients.items():     #群发
                        logging.info(f'{self.client_address} send:<%%% {data_makefile} %%%> to {k}')
                        i.wfile.write(msg)


        except ConnectionAbortedError:
            print(f'{self.client_address}程序退出')
            #self.finish()

    def finish(self) -> None:
        super().finish()
        self.event.set()

server = socketserver.ThreadingTCPServer(('127.0.0.1',8888),Myhandler)
threading.Thread(target=server.serve_forever,name='forever',daemon=True).start()
server.daemon_threads = True

while True:
    cmd = input('>>>')
    if cmd == 'quit':

        server.server_close()
        break


